정적 프로그램과 동적 프로세스
정적 프로그램과 동적 프로세스의 구분
E. 다익스트라
다익스트라는 GOTO 에세이(1968년)에서 이렇게 말한다.
We should do (as wise programmers aware of our limitations) our utmost to shorten the conceptual gap beween the static program and the dynamic process, to make the correspondence between the program (spread out in text space) and the process (spread out in time) as trivial as possible. —Go to statement considered harmful
폰 노이먼
좀 더 과거로 가면 1945년 존 폰 노이먼과 Herman Goldstine이 쓴 보고서 Planning and coding of problems for an electronic computing instrument에서도 유사한 표현이 나온다.
C scans the sequence of codes, and effects the instructions, which they contain, one by one. If this were just a linear scanning of the coded sequence, the latter remaining throughout the procedure unchanged in form, then matters would be quite simple…. This, however, is not the case. We are convinced, both on general grounds and from our actual experience with the coding of specific numerical problems, that the main difficulty lies just at this point…. C will, in general, not scan the coded sequence of instructions linearly. It may jump occasionally forward or backward, omitting (for the time being, but probably not permanently) some parts of the sequence, and going repeatedly through others. It may modify some parts of the sequence while obeying the instructions in another part of the sequence…. Thus the relation of the coded instruction sequence to the mathematically conceived procedure of (numerical) solution is not a statical one, that of a translation, but highly dynamical…. These complications are, furthermore, not hypothetical or exceptional. It does not require a deep analysis of any inductive or iterative mathematical process to see that they are indeed the norm.
위 글에서 “C”는 프로그램 카운터 또는 인스트럭션 포인터 또는 현재 실행 중인 행을 말한다. “Selectron memory”는 예전에 쓰던 메모리 장치를 말하고 요즘 용어로 치면 램이다. 위 인용에서는 데이터 뿐 아니라 코드도 실행 중에 동적으로 바뀌는 상황을 상정하고 있는 점도 눈에 띈다. 요즘에는 매우 예외적인 상황(예: 의도적으로 코드의 동작을 이해하기 어렵게 만들려는 경우, 버퍼 오버플로우 등 해킹을 하기 위한 경우 등)이 아니라면 실행 중 코드를 변경하지 않거나 매우 통제된 방식으로만 코드 변경을 지원한다. 심지어 몇몇 언어(주로 함수형 언어)에서는 변수의 값도 불변으로 제약한다.
한편, Aspect-oriented software development에 의하면 프로그래밍 언어의 발전은 정적 프로그램과 동적 프로세스 사이의 대응을 약화하는 방향으로 이루어졌다고:
The earliest computer machine-language programs had a strict correspondence between the program text and the execution pattern. Generally, each programming language statement was both unitary and local - unitary in that it ended up having effect in precisely one place in the elaborated program, and local in that it was almost always proximate to the statements executing around it
The history (of this part) of programming languages has been about moving away from purely local and unitary languages and toward mechanisms that let the programmer separate concepts into pragmatic assemblages or mudles, instead of being tied to saying things just where they happen. The first exceptions to locality were subprograms (i.e., procedures, subroutines, functions). Subprograms were a great invention, enabling abstracting out some behavior to someplace else, They have many virtues for separating concerns. …
Inheritance (and related mechanisms like delegation) in OOP was another important introduction of non-locality. Executing inherited behavior is non-local. —p22, Aspect-oriented software development
이 두 견해는 상충되는 것 같지만 그렇지 않다.
정적 프로그램과 동적 프로세스 사이의 간극을 줄이는 게 좋다고 말하는 이유는 단일 모듈 내에서는 그렇게 하는 게 프로그래머의 인지부하를 낮춰주기 때문이다. 한 함수에 담긴 여러 문장들의 추상성 수준이 일관되게 유지되는 게 좋은 이유도 그래야 한 함수를 읽다말고 다른 함수를 읽기 위해 이리저리 옮겨다닐 필요성이 줄기 때문.
정적 프로그램과 동적 프로세스 사이의 대응을 약화하는 게 좋다고 말하는 이유는 서로 다른 관심사를 다루는 모듈들을 격리함으로써 결과적으로 단일 모듈 내에서 정적 프로그램과 동적 프로세스 사이의 간극을 줄일 수 있게 되기 때문이다.
- OOP에서의 상속은 의존성 역전을 통해 상위 모듈의 관심사 안에 하위 모듈의 관심사가 엮여 들어가지 않게 만들어준다.
- AOP에서는 동적으로 엮이는(Aspect weaving) 다차원적 관심사를 특정 관심사에 기반하여 정적인 2차원 공간에 사영(projection)하면 나머지 관심사들이 흩어질 수 밖에 없다는 문제(지배적 분해에 의한 폭정)를 해결하기 위해 애스펙트라는 모듈화 단위를 도입한다.
- 구조적 프로그래밍의 서브 루틴도 마찬가지.
하나의 관심사를 다루는 모듈 내에서 정적 프로그램과 동적 프로세스의 간극을 줄이는 게 중요한데, 이를 달성하기 위해서는 필요에 따라 둘 사이의 대응을 적절히 분리할 수도 있어야 한다는 말로 이해하면 두 관점 사이에 충돌은 없다.